import httplib2
import time
import json
class OdlUtil:
    url = ''
    def __init__(self, host, port):
        self.url = 'http://' + host + ':' + str(port)
    def install_flow(self, container_name='default',username="admin", password="admin"):
        http = httplib2.Http()
        http.add_credentials(username, password)
        headers = {'Accept': 'application/json'}
        flow_name = 'flow_' + str(int(time.time()*1000))
        #s2流表
	#将处理完服务器的数据包发送给实时检测并返回给s1
        s2_to_s1_h21 ='''
		{
			"flow": [
			{
				"id": "0",
					"match": {
						"ethernet-match":{
							"ethernet-type": {"type": "2048"}
						},
				    	},
				    	"instructions": {
					    	"instruction": [
						    	{
							    	"order": "0",
							    	"apply-actions": 
							    	{
								    	"action": [
									    	{
										    	"output-action": {
										    		"output-node-connector": "2"
										    	},
										    	"order": "0"
									    	},
									    	{
										    	"output-action": {
										    		"output-node-connector": "1"
										    	},
										    	"order": "1"
									    	}
								    	]
							    	}
						    	}
					    	]
				    	},
			    	"priority": "0","table_id": "0"
			 }]
		}
                    '''
        #处理发给资源管理系统的包
        s2_to_s1 ='''
		{
			"flow": [
			{
				"id": "1",
					"match": {
						"ethernet-match":{
							"ethernet-type": {"type": "2048"}
						},
						"ipv4-destination": "192.168.1.2/32"
				    	},
				    	"instructions": {
					    	"instruction": [
						    	{
							    	"order": "0",
							    	"apply-actions": 
							    	{
								    	"action": [
									    	{
										    	"output-action": {
										    		"output-node-connector": "1"
										    	},
										    	"order": "1"
									    	}
								    	]
							    	}
						    	}
					    	]
				    	},
			    	"priority": "100","table_id": "0"
			 }]
		}
                    '''
        s2_to_server1_server2_server1 ='''
		{
			"flow": [
			{
				"id": "2",
					"match": {
						"ethernet-match":{
							"ethernet-type": {"type": "2048"}
						},
					    	"ipv4-destination": "192.168.1.1/32"
				    	},
				    	"instructions": {
					    	"instruction": [
						    	{
							    	"order": "0",
							    	"apply-actions": 
							    	{
								    	"action": [
									    	{
										    	"output-action": {
										    		"output-node-connector": "3"
										    	},
										    	"order": "0"
									    	}
								    	]
							    	}
						    	}
					    	]
				    	},
			    	"priority": "101","table_id": "0"
			 }]
		}
                    '''
        s2_to_server1_server2_server2 ='''
		{
			"flow": [
			{
				"id": "3",
					"match": {
						"ethernet-match":{
							"ethernet-type": {"type": "2048"}
						},
					    	"ipv4-destination": "192.168.1.1/32"
				    	},
				    	"instructions": {
					    	"instruction": [
						    	{
							    	"order": "0",
							    	"apply-actions": 
							    	{
								    	"action": [
									    	{
										    	"output-action": {
										    		"output-node-connector": "4"
										    	},
										    	"order": "0"
									    	}
								    	]
							    	}
						    	}
					    	]
				    	},
			    	"priority": "100","table_id": "0"
			 }]
		}
                    '''
        s2_to_server2_server1_server1 ='''
		{
			"flow": [
			{
				"id": "2",
					"match": {
						"ethernet-match":{
							"ethernet-type": {"type": "2048"}
						},
					    	"ipv4-destination": "192.168.1.1/32"
				    	},
				    	"instructions": {
					    	"instruction": [
						    	{
							    	"order": "0",
							    	"apply-actions": 
							    	{
								    	"action": [
									    	{
										    	"output-action": {
										    		"output-node-connector": "3"
										    	},
										    	"order": "0"
									    	}
								    	]
							    	}
						    	}
					    	]
				    	},
			    	"priority": "100","table_id": "0"
			 }]
		}
		    '''
        s2_to_server2_server1_server2 ='''
		{
			"flow": [
			{
				"id": "3",
					"match": {
						"ethernet-match":{
							"ethernet-type": {"type": "2048"}
						},
					    	"ipv4-destination": "192.168.1.1/32"
				    	},
				    	"instructions": {
					    	"instruction": [
						    	{
							    	"order": "0",
							    	"apply-actions": 
							    	{
								    	"action": [
									    	{
										    	"output-action": {
										    		"output-node-connector": "4"
										    	},
										    	"order": "0"
									    	}
								    	]
							    	}
						    	}
					    	]
				    	},
			    	"priority": "101","table_id": "0"
			 }]
		}
		    '''
        headers = {'Content-type': 'application/json'}

        #下发流表，地址由ODL上获得
        #下发s2的固定流表
        response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/0', body=s2_to_s1_h21, method='PUT',headers=headers)   
        response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/1', body=s2_to_s1, method='PUT',headers=headers)

        while 1 :
            s2_server1_uri = 'http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:2/node-connector/openflow:2:3'
            s2_server2_uri = 'http://127.0.0.1:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:2/node-connector/openflow:2:4'
            #获取s2端口3和s2端口4的流量
            response, content = http.request(uri=s2_server1_uri, method='GET')
            content = json.loads(content.decode())
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s2_server1_bytes1 = statistics['bytes']['transmitted']
            response, content = http.request(uri=s2_server2_uri, method='GET')
            content = json.loads(content.decode())
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s2_server2_bytes1 = statistics['packets']['transmitted']
            #0.5秒后再次获取
            time.sleep(1)
            response, content = http.request(uri=s2_server1_uri, method='GET')
            content = json.loads(content.decode())
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s2_server1_bytes2 = statistics['bytes']['transmitted']
            response, content = http.request(uri=s2_server2_uri, method='GET')
            content = json.loads(content.decode())
            statistics = content['node-connector'][0]['opendaylight-port-statistics:flow-capable-node-connector-statistics']
            s2_server2_bytes2 = statistics['packets']['transmitted']

            s2_server1_transmitted=s2_server1_bytes2-s2_server1_bytes1
            s2_server2_transmitted=s2_server2_bytes2-s2_server2_bytes1
            if s2_server1_transmitted <= s2_server2_transmitted :
                print(' server1处理消息较少，server1改为较高优先级')
                response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/2', body=s2_to_server1_server2_server1, method='PUT',headers=headers)
                response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/3', body=s2_to_server1_server2_server2, method='PUT',headers=headers)
            else :
                print(' server2处理消息较少，server2改为较高优先级')
                response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/2', body=s2_to_server2_server1_server1, method='PUT',headers=headers)
                response, content = http.request(uri='http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:2/flow-node-inventory:table/0/flow/3', body=s2_to_server2_server1_server2, method='PUT',headers=headers)

            
odl = OdlUtil('127.0.0.1', '8181')
odl.install_flow()
